package com.zsj.advice;

import com.zsj.context.ThreadLocalContext;
import com.zsj.entity.WebResponse;
import com.zsj.enums.ErrorCodeEnum;
import com.zsj.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.annotation.MethodArgumentConversionNotSupportedException;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.multipart.support.MissingServletRequestPartException;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**
 * @Description:
 * @Author:
 * @Date:
 */
@Slf4j
@ControllerAdvice
public class ResultProAdvice implements ResponseBodyAdvice {

    @Override
    public boolean supports(MethodParameter returnType, Class obj) {
        return true;
    }

    @ExceptionHandler(Exception.class)
    @ResponseBody
    WebResponse handleException(Exception e) {
        if (e instanceof MissingServletRequestParameterException
                || e instanceof MissingServletRequestPartException
                || e instanceof MethodArgumentConversionNotSupportedException
                || e instanceof MethodArgumentTypeMismatchException) {
            log.error("Exception", e);
            return WebResponse.fail(ErrorCodeEnum.PARAM_ERROR);
        } else if (e instanceof BusinessException) {
            log.error("BusinessException", e);
            return WebResponse.fail(((BusinessException) e).getErrorCodeEnum());
        } else {
            log.error("Exception", e);
            return WebResponse.fail(ErrorCodeEnum.SUPPLIER_FAIL);
        }
    }

    @Override
    @ResponseBody
    public Object beforeBodyWrite(Object result, MethodParameter returnType,
                                  MediaType selectedContentType,
                                  Class objClass,
                                  ServerHttpRequest request, ServerHttpResponse response) {

        log.info("beforeBodyWrite result: {}", result);
        if (result instanceof WebResponse) {
            try {
                WebResponse webResponse = (WebResponse) result;
                if (ObjectUtils.isEmpty(webResponse.getData())) {
                    log.info("响应报文中Data为空，需要赋值");
                    webResponse.setData(ThreadLocalContext.RECHARGE_DATA_THREAD_LOCAL.get());
                }
                ThreadLocalContext.RECHARGE_DATA_THREAD_LOCAL.remove();
                MDC.remove("selfUid");
                MDC.remove("dyOrderNo");

                return webResponse;
            } catch (ClassCastException e) {
                log.error("Exception", e);
            }
        }
        return result;
    }

}
